﻿using System;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.Text;
using System.Windows.Forms;

namespace MultiRDP
{
    public partial class Form1 : Form
    {
        private bool Is64Bit;
        private OSType OsType;
        private string FilePath = @"c:\windows\system32\termsrv.dll";

        public Form1()
        {
            InitializeComponent();
            this.Is64Bit = IntPtr.Size == 8;
            var ver = Environment.OSVersion.Version;

            switch (ver.Major)
            {
                case 5:
                    {
                        switch (ver.Minor)
                        {
                            case 0:// 2000
                                this.Text += "(Win 2000)";
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                            case 1:// XP
                                this.Text += "(Win XP)";
                                this.OsType = OSType.Win_XP;
                                break;
                            default:
                                this.Text += "(未知系统版本)";
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                        }
                    }
                    break;
                case 6:
                    {
                        switch (ver.Minor)
                        {
                            case 0:// vista
                                this.Text += "(Win vista)";
                                this.OsType = OSType.Win_Vista;
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                            case 1:// 7
                                this.Text += "(Win 7)";
                                this.OsType = OSType.Win_7;
                                if (this.Is64Bit)
                                {
                                    this.button2.Enabled = this.Is764Cracked();
                                    this.button1.Enabled = !this.button2.Enabled;
                                }
                                else
                                {
                                    this.button1.Enabled = this.button2.Enabled = false;
                                }
                                break;
                            case 2:// 8
                                this.Text += "(Win 8)";
                                this.OsType = OSType.Win_8;
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                            case 3:// 8.1
                                this.Text += "(Win 8.1)";
                                this.OsType = OSType.Win_81;
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                            default:
                                this.Text += "(未知系统版本)";
                                this.button1.Enabled = this.button2.Enabled = false;
                                break;
                        }
                    }
                    break;
                case 10:// 10
                    this.Text += "(Win 10)";
                    this.OsType = OSType.Win10;
                    this.button1.Enabled = !this.Is10Cracked();
                    break;
                default:
                    this.Text += "(未知系统版本)";
                    this.button1.Enabled = this.button2.Enabled = false;
                    break;
            }
            this.Text += "---by wangfs763";
            this.button2.Enabled = this.canRecover();
        }

        #region XP

        bool IsXP32Cracked()
        {
            if (this.Is64Bit) return false;
            string file;
#if DEBUG
            file = @"F:\win10\termsrv.dll";
#else
            file = this.FilePath;
#endif
            using (Stream reader = File.OpenRead(file))
            {
                reader.Position = 328;
                return reader.ReadByte() == 0x17;
            }
        }

        void CrackXP32()
        {
            if (this.Is64Bit) return;
            using (Stream reader = File.Open(this.FilePath, FileMode.Open, FileAccess.ReadWrite))
            {
                reader.Position = 328;
                reader.Write(new byte[] { 0x17, 0x68, 0x04 }, 0, 3);
            }
            StringBuilder sb = new StringBuilder("Windows Registry Editor Version 5.00\r\n");
            sb.AppendLine(@"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]");
            sb.AppendLine("\"SFCDisable\"=dword:ffffff9d");
            sb.AppendLine(@"[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\Licensing Core]");
            sb.AppendLine("\"EnableConcurrentSessions\"=dword:00000001");
            string file = Path.Combine(Application.UserAppDataPath, "reg.reg");
            File.WriteAllText(file, sb.ToString());
            Process.Start("regedit", @" /s " + file);
            File.Delete(file);
        }

        #endregion

        #region 7_32

        bool Is732Cracked()
        {
            if (this.Is64Bit) return false;

            return false;
        }

        #endregion

        #region 7_64

        bool Is764Cracked()
        {
            if (!this.Is64Bit) return false;
            string file;
#if DEBUG
            file = @"F:\win7\termsrv.dll";
#else
            file = this.FilePath;
#endif
            using (Stream reader = File.OpenRead(file))
            {
                reader.Position = 320;
                return reader.ReadByte() == 0x28;
            }
        }

        bool Crack764()
        {
            if (!this.Is64Bit) return false;
            using (Stream reader = File.Open(this.FilePath, FileMode.Open, FileAccess.ReadWrite))
            {
                reader.Position = 320;
                reader.Write(new byte[] { 0x28, 0x52, 0x0b }, 0, 3);
                reader.Position = 95168;
                reader.Write(new byte[] { 0xb8, 0x00, 0x01, 0x00, 0x00, 0x90, 0x89, 0x87, 0x38, 0x06, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }, 0, 18);
            }
            return true;
        }

        #endregion

        #region 10

        bool Is10Cracked()
        {
            string file;
#if DEBUG
            file = @"F:\win10\termsrv_1703.dll";
#else
            file = this.FilePath;
#endif
            using (Stream reader = File.OpenRead(file))
            {
                byte[] buff = new byte[1024];
                int i;
                while (reader.Read(buff, 0, 1024) > 0)
                {
                    i = 5;
                    while (i < 1024)
                    {
                        if (buff[i] == 0xb8 && buff[i + 1] == 0 && buff[i + 2] == 1 && buff[i + 3] == 0 && buff[i + 4] == 0 && buff[i + 5] == 0x89)
                        {
                            return true;
                        }
                        i += 16;
                    }
                }
            }
            return false;
        }

        bool Crack10()
        {
            using (Stream reader = File.Open(this.FilePath, FileMode.Open, FileAccess.ReadWrite))
            {
                byte[] buff = new byte[1024];
                int i;
                while (reader.Read(buff, 0, 1024) > 0)
                {
                    i = 5;
                    while (i < 1024)
                    {
                        if (buff[i] == 0x39 && buff[i + 1] == 0x81 && buff[i + 2] == 0x3c && buff[i + 3] == 6 && buff[i + 4] == 0 && buff[i + 5] == 0)
                        {
                            reader.Position -= (1024 - i);
                            reader.Write(new byte[12] { 0xB8, 00, 01, 00, 00, 0x89, 0x81, 0x38, 06, 00, 00, 0x90 }, 0, 12);
                            return true;
                        }
                        i += 16;
                    }
                }
            }
            return false;
        }

        #endregion

        void backup(Func<bool> patch)
        {
            var sc = new System.ServiceProcess.ServiceController("TermService");
            bool running = sc.Status == System.ServiceProcess.ServiceControllerStatus.Running;
            if (running) sc.Stop();

            var fv = FileVersionInfo.GetVersionInfo(this.FilePath);
            File.Copy(this.FilePath, $"termsrv_{fv.FileBuildPart}.dll", true);

            this.getAccess();
            bool b = patch();
            if (running) sc.Start();

            MessageBox.Show($"破解{(b ? "完成" : "失败")}");
        }
        void getAccess()
        {
            Process.Start(new ProcessStartInfo("takeown", "/F " + this.FilePath) { UseShellExecute = false, CreateNoWindow = true }).WaitForExit();

            var fi = new FileInfo(this.FilePath);
            var uac = fi.GetAccessControl();
            bool b = false;
            foreach (System.Security.AccessControl.AuthorizationRule r in uac.GetAccessRules(true, true, typeof(NTAccount)))
            {
                if (b = r.IdentityReference.Value.EndsWith("Users")) break;
            }
            var ur = new System.Security.AccessControl.FileSystemAccessRule("Users", System.Security.AccessControl.FileSystemRights.FullControl, System.Security.AccessControl.AccessControlType.Allow);
            if (b) uac.SetAccessRule(ur); else uac.AddAccessRule(ur);
            fi.SetAccessControl(uac);
        }
        bool canRecover()
        {
            var fv = FileVersionInfo.GetVersionInfo(this.FilePath);
            return !this.button1.Enabled && File.Exists($"termsrv_{fv.FileBuildPart}.dll");
        }

        // 破解
        private void button1_Click(object sender, EventArgs e)
        {
            switch (this.OsType)
            {
                case OSType.Win_7:
                    if (this.Is64Bit) this.backup(this.Crack764);
                    break;
                case OSType.Win_8:
                    break;
                case OSType.Win_81:
                    break;
                case OSType.Win_XP:
                    this.CrackXP32();
                    break;
                case OSType.Win10:
                    this.backup(this.Crack10);
                    break;
                default:
                    MessageBox.Show("不支持的系统！");
                    break;
            }
        }
        // 还原
        private void button2_Click(object sender, EventArgs e)
        {
            var sc = new System.ServiceProcess.ServiceController("TermService");
            bool running = sc.Status == System.ServiceProcess.ServiceControllerStatus.Running;
            if (running) sc.Stop();
            this.getAccess();

            var fv = FileVersionInfo.GetVersionInfo(this.FilePath);
            File.Copy($"termsrv_{fv.FileBuildPart}.dll", this.FilePath, true);

            if (running) sc.Start();
            MessageBox.Show("还原完成");
        }
    }


    enum OSType
    {
        Win_XP,
        Win_Vista,
        Win_7,
        Win_8,
        Win_81,
        Win10
    }

}
